package org.common.container;

import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import java.util.SortedSet;
import java.util.TreeSet;
import org.graph.base.Node;
import org.graph.base.Edge;
import org.graph.base.Edge.Direction;

import org.objective.base.CommonObject;
import org.common.treebuilder.TreeNodeCollection;

/**
 *
 * @author gus
 */
class TreeNodeCollectionImpl<T extends CommonObject> implements TreeNodeCollection<Node<Long, T>, T>
{
    private final Container<T> container;
    private Node<Long, T> parent;

    public TreeNodeCollectionImpl(Container<T> container, Node<Long, T> parent)
    {
        this.container = container;
        this.parent = parent;
        if(parent == null)
        {
            this.parent = container.dummyNode;
        }
    }

    @Override
    public Comparator<Node<Long, T>> getComparator()
    {
        return null;
    }

    @Override
    public Node<Long, T> createTreeNode(T object) throws Exception
    {
        return container.createTreeNode(object, parent);
    }

    @Override
    public void removeTreeNode(Node<Long, T> node) throws Exception
    {
        container.removeTreeNode(node);
    }

    @Override
    public boolean contains(Node<Long, T> node)
    {
        try
        {
            return container.storage.isExistEdge(parent, node, Direction.DIRECT);
        }
        catch (Exception e)
        {
        }
        return false;
    }

    @Override
    public boolean isEmpty()
    {
        return !container.storage.adjNodeIterator(parent).hasNext();
    }

    @Override
    public Iterator<Node<Long, T>> iterator()
    {
        List<Edge<Node<Long, T>, Long>> list = container.storage.findProceedEdges(parent, Direction.DIRECT);
        SortedSet<Node<Long, T>> store = new TreeSet<Node<Long, T>>(new DefaultComparator());

        for (Edge<Node<Long, T>, Long> edge : list)
        {
            store.add(edge.anotherNode(parent));
        }
        return store.iterator();
    }

    @Override
    public Node<Long, T> findNode(T object)
    {
        for(Node<Long, T> node : this )
        {
            if(node.getData().getOid() == object.getOid())
            {
                return node;
            }
        }
        return null;
    }

    @Override
    public int size()
    {
        return container.storage.findProceedEdges(parent, Direction.DIRECT).size();
    }

    private class DefaultComparator implements Comparator<Node<Long, T>>
    {
        @Override
        public int compare(Node<Long, T> o1, Node<Long, T> o2)
        {
            return o1.getKey().compareTo(o2.getKey());
        }
    }
}
